package config

import (
	"fmt"

	"github.com/spf13/viper"
)

func init() {
	//绑定环境变量
	for k, v := range bindEnv {
		_ = viper.BindEnv(k, v)
	}
	//设置默认值
	for k, v := range bindDefault {
		viper.SetDefault(k, v)
	}
}

// 加载配置文件
func LoadFromFile(file string) error {
	//viper.Debug()
	//设置要读取的配置文件
	viper.SetConfigFile(file)
	//自动读取环境变量
	viper.AutomaticEnv()
	// 查找并读取配置文件
	if err := viper.ReadInConfig(); err != nil {
		return fmt.Errorf("Fatal error config file: %s \n", err)
	}
	//将配置内容填充到结构体
	if err := viper.Unmarshal(&Config); err != nil {
		return fmt.Errorf("unable to decode into struct, %v", err)
	}
	//配置文件修改后自动重载
	/*viper.OnConfigChange(func(e fsnotify.Event) {
		_ = viper.ReadInConfig()
		_ = viper.Unmarshal(&config.Config)
	})
	//监控配置文件变化
	viper.WatchConfig()*/

	return nil
}

// 配置内容与环境变量的关联关系
var bindEnv = map[string]string{
	"app.debug":     "APP_DEBUG",
	"app.env":       "GIN_MODE",
	"app.host":      "APP_HOST",
	"app.port":      "APP_PORT",
	"app.log_level": "LOG_LEVEL",
}

// 默认的配置
var bindDefault = map[string]interface{}{
	"app.host":      "0.0.0.0",
	"app.port":      8080,
	"app.env":       "dev",
	"app.debug":     true,
	"app.log_level": "INFO",
}

type Conf struct {
	App      *AppConfig                 `mapstructure:"app"`      //应用基础配置
	Biz      *BizConfig                 `mapstructure:"biz"`      //业务相关配置
	Logger   *LoggerConfig              `mapstructure:"logger"`   //日志相关配置
	Storage  *StorageConfig             `mapstructure:"storage"`  //存储相关配置
	Database map[string]*DatabaseConfig `mapstructure:"database"` //数据库相关配置
	Redis    map[string]*RedisConfig    `mapstructure:"redis"`    //redis相关配置
	Cache    map[string]*CacheConfig    `mapstructure:"cache"`    //缓存相关配置
}

var Config = &Conf{
	App:      DefaultAppConfig,
	Biz:      DefaultBizConfig,
	Logger:   DefaultLoggerConfig,
	Storage:  DefaultStorageConfig,
	Database: map[string]*DatabaseConfig{"default": DefaultDatabaseConfig},
	Redis:    map[string]*RedisConfig{"default": DefaultRedisConfig},
	Cache:    map[string]*CacheConfig{"default": DefaultCacheConfig},
}
